import java.awt.Color;
import java.awt.Point;
import java.io.Serializable;

import java.util.ArrayList;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class WhiteBoardClient implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 4467166359490445706L;

	private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;

	private WhiteBoardModel model;
	private InteractingBoard board;

	private Color color = Color.black;

	private String name = "default client";

	TopicConnection connection;

	Publisher loginPublisher;
	Publisher linePublisher;
	Publisher logoutPublisher;
	Subscriber recvSubscriber;

	Subscriber clearSubscriber;

	public WhiteBoardModel getModel() {
		return model;
	}

	public InteractingBoard getBoard() {
		return board;
	}

	public Color getColor() {
		return color;
	}

	public void setColor(Color color) {
		this.color = color;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {

		this.name = name;

	}

	public WhiteBoardClient() {

		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() {
				try {
					ArrayList<Serializable> lst = new ArrayList<Serializable>();
					lst.add(name);
					ObjectMessage om;
					om = logoutPublisher.getSession().createObjectMessage(lst);
					logoutPublisher.getPub().send(om);
					connection.close();
				} catch (JMSException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		});

		model = new WhiteBoardModel();
		board = new InteractingBoard(this);

	}

	public void receiveLine(Point start, Point end, Color color) {
		model.addLine(start, end, color);
		board.repaint();

	}

	public void connect() {

		try {
			TopicConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
			connection = connectionFactory.createTopicConnection();

			loginPublisher = new Publisher("Login", connection);
			linePublisher = new Publisher("Line", connection);
			logoutPublisher = new Publisher("Logout", connection);


			connection.start();

			// Client receives either all lines from the server or filters non-relevant ones.
			recvSubscriber = new Subscriber("Recv", connection, /*"name='" + name + "'" */ null);
			recvSubscriber.getSub().setMessageListener(new MessageListener() {

				@Override
				public void onMessage(Message m) {
					ObjectMessage msg = (ObjectMessage) m;
					try {
						ArrayList<Serializable> lst = (ArrayList<Serializable>) msg.getObject();
						receiveLine((Point) lst.get(0), (Point) lst.get(1), (Color) lst.get(2));

					} catch (JMSException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}

			});
			clearSubscriber = new Subscriber("Clear", connection, null);
			clearSubscriber.getSub().setMessageListener(new MessageListener() {

				@Override
				public void onMessage(Message m) {
					model.clear();
					board.repaint();

				}

			});
			
			ArrayList<Serializable> lst = new ArrayList<Serializable>();
			lst.add(name);
			lst.add(color);
			ObjectMessage om;
			om = loginPublisher.getSession().createObjectMessage(lst);
			loginPublisher.getPub().send(om);
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void sendLine(Point start, Point end) {

		try {
			ArrayList<Serializable> lst = new ArrayList<Serializable>();
			lst.add(name);
			lst.add(start);
			lst.add(end);

			ObjectMessage om;
			om = linePublisher.getSession().createObjectMessage(lst);
			linePublisher.getPub().send(om);
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
